{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# AGiXT Python SDK Tests\n",
    "\n",
    "## Register a user"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "import string\n",
    "import time\n",
    "import openai\n",
    "from agixtsdk import AGiXTSDK\n",
    "import requests\n",
    "import os\n",
    "import re\n",
    "\n",
    "\n",
    "def display_content(content):\n",
    "    outputs_url = f\"http://localhost:7437/outputs/\"\n",
    "    os.makedirs(\"outputs\", exist_ok=True)\n",
    "    try:\n",
    "        from IPython.display import Audio, display, Image, Video\n",
    "    except:\n",
    "        print(content)\n",
    "        return\n",
    "    if \"http://localhost:8091/outputs/\" in content:\n",
    "        if outputs_url != \"http://localhost:8091/outputs/\":\n",
    "            content = content.replace(\"http://localhost:8091/outputs/\", outputs_url)\n",
    "    if outputs_url in content:\n",
    "        urls = re.findall(f\"{re.escape(outputs_url)}[^\\\"' ]+\", content)\n",
    "        urls = urls[0].split(\"\\n\\n\")\n",
    "        for url in urls:\n",
    "            file_name = url.split(\"/\")[-1]\n",
    "            url = f\"{outputs_url}{file_name}\"\n",
    "            data = requests.get(url, headers=agixt.headers).content\n",
    "            if url.endswith(\".jpg\") or url.endswith(\".png\"):\n",
    "                content = content.replace(url, \"\")\n",
    "                display(Image(url=url))\n",
    "            elif url.endswith(\".mp4\"):\n",
    "                content = content.replace(url, \"\")\n",
    "                display(Video(url=url, autoplay=True))\n",
    "            elif url.endswith(\".wav\"):\n",
    "                content = content.replace(url, \"\")\n",
    "                display(Audio(url=url, autoplay=True))\n",
    "    print(content)\n",
    "\n",
    "\n",
    "failures = 0\n",
    "random_string = \"\".join(\n",
    "    random.choices(string.ascii_uppercase + string.digits, k=10)\n",
    ").lower()\n",
    "test_email = f\"{random_string}@test.com\"\n",
    "agixt = AGiXTSDK(base_uri=\"http://localhost:7437\", verbose=True)\n",
    "\n",
    "while failures < 100:\n",
    "    try:\n",
    "        otp_uri = agixt.register_user(\n",
    "            email=test_email, first_name=\"Test\", last_name=\"User\"\n",
    "        )\n",
    "        openai.base_url = \"http://localhost:7437/v1/\"\n",
    "        openai.api_key = agixt.headers[\"Authorization\"]\n",
    "        openai.api_type = \"openai\"\n",
    "        break\n",
    "    except Exception as e:\n",
    "        print(e)\n",
    "        failures += 1\n",
    "        time.sleep(5)\n",
    "\n",
    "# Show QR code for MFA setup\n",
    "import qrcode\n",
    "from IPython.display import Image\n",
    "\n",
    "qr = qrcode.QRCode()\n",
    "qr.add_data(otp_uri)\n",
    "qr.make(fit=True)\n",
    "img = qr.make_image(fill=\"black\", back_color=\"white\")\n",
    "img.save(\"qr.png\")\n",
    "Image(filename=\"qr.png\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Confirm user exists\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "user_exists = agixt.user_exists(email=test_email)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Update User's Name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "update_user = agixt.update_user(first_name=\"Super\", last_name=\"Man\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get User Details"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "user_details = agixt.get_user()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## Get a list of Providers\n",
    "\n",
    "This will get a list of AI Providers available to use with AGiXT.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "providers = agixt.get_providers()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get a list of Providers for a services\n",
    "\n",
    "- Service options are `llm`, `tts`, `image`, `embeddings`, `transcription`, and `translation`.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "services = agixt.get_providers_by_service(service=\"tts\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Default Provider Settings\n",
    "\n",
    "Choose a provider from the list of AI providers and get the default settings for that provider.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "provider_name = \"ezlocalai\"\n",
    "provider_settings = agixt.get_provider_settings(provider_name=provider_name)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Embedding Providers\n",
    "\n",
    "Embedding providers are used to embed information to vectors to store in the vector database to be searched for context injection.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "embed_providers = agixt.get_embed_providers()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Extension Settings\n",
    "\n",
    "This is where we get all third party extension settings for the agent with defaults to fill in when there is nothing entered on the front end.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ext_settings_resp = agixt.get_extension_settings()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "from pprint import pprint\n",
    "\n",
    "response = requests.get(\n",
    "    f\"{agixt.base_uri}/v1/extension/categories\", headers=agixt.headers\n",
    ")\n",
    "pprint(response.json())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Webhook Tests\n",
    "\n",
    "This section tests the webhook system endpoints including incoming and outgoing webhooks using the AGiXT SDK."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test creating an outgoing webhook using requests\n",
    "from datetime import datetime\n",
    "import json\n",
    "\n",
    "outgoing_webhook_data = {\n",
    "    \"name\": \"Test Webhook\",\n",
    "    \"description\": f\"Test webhook created at {datetime.now().isoformat()}\",\n",
    "    \"target_url\": \"https://webhook.site/test\",\n",
    "    \"event_types\": [\"agent.created\", \"agent.deleted\"],\n",
    "    \"active\": True,\n",
    "    \"headers\": {\"Content-Type\": \"application/json\"},\n",
    "    \"secret\": \"test-secret-123\",\n",
    "}\n",
    "\n",
    "# Using requests to create webhook\n",
    "response = requests.post(\n",
    "    \"http://localhost:7437/api/webhooks/outgoing\",\n",
    "    json=outgoing_webhook_data,\n",
    "    headers=agixt.headers,\n",
    ")\n",
    "print(f\"Created outgoing webhook: {response.status_code} - {response.json()}\")\n",
    "created_webhook = response.json() if response.status_code == 200 else None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test listing outgoing webhooks using requests\n",
    "response = requests.get(\n",
    "    \"http://localhost:7437/api/webhooks/outgoing\",\n",
    "    headers=agixt.headers,\n",
    ")\n",
    "print(f\"Get webhooks response: {response.status_code}\")\n",
    "if response.status_code == 200:\n",
    "    webhooks = response.json()\n",
    "    print(f\"Found {len(webhooks)} outgoing webhooks\")\n",
    "    for webhook in webhooks:\n",
    "        print(\n",
    "            f\"  - {webhook.get('name', 'Unnamed')}: {webhook.get('target_url', 'No URL')}\"\n",
    "        )\n",
    "else:\n",
    "    print(f\"Error getting webhooks: {response.text}\")\n",
    "    webhooks = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test creating an incoming webhook for an agent using requests\n",
    "agent_name = \"new_agent\"\n",
    "incoming_webhook_data = {\n",
    "    \"name\": \"GitHub Webhook\",\n",
    "    \"description\": \"Webhook for GitHub events\",\n",
    "    \"agent_name\": agent_name,\n",
    "    \"secret\": \"github-secret-123\",\n",
    "    \"transform_template\": json.dumps(\n",
    "        {\n",
    "            \"action\": \"{{ action }}\",\n",
    "            \"repository\": \"{{ repository.name }}\",\n",
    "            \"sender\": \"{{ sender.login }}\",\n",
    "        }\n",
    "    ),\n",
    "}\n",
    "\n",
    "response = requests.post(\n",
    "    \"http://localhost:7437/api/webhooks/incoming\",\n",
    "    json=incoming_webhook_data,\n",
    "    headers=agixt.headers,\n",
    ")\n",
    "print(\n",
    "    f\"Created incoming webhook: {response.status_code} - {response.json() if response.status_code == 200 else response.text}\"\n",
    ")\n",
    "incoming_webhook = response.json() if response.status_code == 200 else None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test incoming webhook with agent_id parameter (alternative format)\n",
    "print(\"--- Testing incoming webhook with agent_id parameter ---\")\n",
    "\n",
    "# Get the user details which contains the agent_id\n",
    "user_details = agixt.get_user()\n",
    "agent_id = (\n",
    "    user_details[\"companies\"][0][\"agents\"][0][\"id\"]\n",
    "    if user_details and user_details.get(\"companies\")\n",
    "    else None\n",
    ")\n",
    "\n",
    "if agent_id:\n",
    "    print(f\"Found user agent_id: {agent_id}\")\n",
    "\n",
    "    incoming_webhook_data_with_id = {\n",
    "        \"name\": \"Agent ID Test Webhook\",\n",
    "        \"description\": \"Testing webhook creation with agent_id parameter\",\n",
    "        \"agent_id\": agent_id,  # Using agent_id instead of agent_name\n",
    "        \"secret\": \"agent-id-secret-456\",\n",
    "        \"transform_template\": json.dumps(\n",
    "            {\"event\": \"{{ event_type }}\", \"data\": \"{{ data }}\"}\n",
    "        ),\n",
    "    }\n",
    "\n",
    "    response = requests.post(\n",
    "        \"http://localhost:7437/api/webhooks/incoming\",\n",
    "        json=incoming_webhook_data_with_id,\n",
    "        headers=agixt.headers,\n",
    "    )\n",
    "\n",
    "    print(f\"Incoming webhook with agent_id: {response.status_code}\")\n",
    "    if response.status_code == 200:\n",
    "        print(\"✅ Successfully created incoming webhook using agent_id parameter\")\n",
    "        agent_id_webhook = response.json()\n",
    "        print(f\"Webhook ID: {agent_id_webhook.get('id', 'Unknown')}\")\n",
    "    else:\n",
    "        print(f\"❌ Failed to create webhook with agent_id: {response.text}\")\n",
    "else:\n",
    "    print(\"❌ Could not get agent_id from user details, skipping agent_id test\")\n",
    "\n",
    "print(\"--- Agent ID parameter test completed ---\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test webhook event emission\n",
    "# This would trigger any configured webhooks for agent events\n",
    "test_agent = \"webhook_test_agent\"\n",
    "\n",
    "# Create an agent to trigger webhook events\n",
    "agixt.add_agent(\n",
    "    agent_name=test_agent,\n",
    "    settings={\n",
    "        \"mode\": \"prompt\",\n",
    "        \"prompt_category\": \"Default\",\n",
    "        \"prompt_name\": \"Think About It\",\n",
    "        \"persona\": \"\",\n",
    "    },\n",
    ")\n",
    "print(f\"Created agent {test_agent}, webhook events should have been triggered\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test webhook logs and statistics using requests\n",
    "# Get webhook statistics\n",
    "stats_response = requests.get(\n",
    "    \"http://localhost:7437/api/webhooks/stats\",\n",
    "    headers=agixt.headers,\n",
    ")\n",
    "if stats_response.status_code == 200:\n",
    "    webhook_stats = stats_response.json()\n",
    "    print(f\"Webhook statistics: {json.dumps(webhook_stats, indent=2)}\")\n",
    "else:\n",
    "    print(f\"Error getting webhook stats: {stats_response.text}\")\n",
    "\n",
    "# Get webhook logs\n",
    "logs_response = requests.get(\n",
    "    \"http://localhost:7437/api/webhooks/logs?limit=10\",\n",
    "    headers=agixt.headers,\n",
    ")\n",
    "if logs_response.status_code == 200:\n",
    "    webhook_logs = logs_response.json()\n",
    "    print(f\"Found {len(webhook_logs)} webhook log entries\")\n",
    "    if webhook_logs:\n",
    "        print(f\"Latest log: {webhook_logs[0]}\")\n",
    "else:\n",
    "    print(f\"Error getting webhook logs: {logs_response.text}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Additional webhook validation tests\n",
    "print(\"=== Running additional webhook validation tests ===\")\n",
    "\n",
    "# Test 1: Verify webhook creation response structure\n",
    "if created_webhook and isinstance(created_webhook, dict):\n",
    "    required_fields = [\"id\", \"name\", \"target_url\", \"event_types\", \"active\"]\n",
    "    missing_fields = [\n",
    "        field for field in required_fields if field not in created_webhook\n",
    "    ]\n",
    "    if missing_fields:\n",
    "        print(f\"❌ Created webhook missing required fields: {missing_fields}\")\n",
    "    else:\n",
    "        print(\"✅ Created webhook has all required fields\")\n",
    "\n",
    "    # Verify field types\n",
    "    if \"id\" in created_webhook and not isinstance(created_webhook[\"id\"], str):\n",
    "        print(f\"❌ Webhook ID should be string, got {type(created_webhook['id'])}\")\n",
    "    else:\n",
    "        print(\"✅ Webhook ID is properly formatted as string\")\n",
    "else:\n",
    "    print(\"❌ Webhook creation failed - cannot validate response structure\")\n",
    "\n",
    "# Test 2: Test webhook with different event types\n",
    "print(\"\\n--- Testing webhook with different event types ---\")\n",
    "event_test_data = {\n",
    "    \"name\": \"Event Test Webhook\",\n",
    "    \"description\": \"Testing different event types\",\n",
    "    \"target_url\": \"https://httpbin.org/post\",\n",
    "    \"event_types\": [\"conversation.started\", \"conversation.ended\", \"memory.added\"],\n",
    "    \"active\": True,\n",
    "}\n",
    "\n",
    "event_response = requests.post(\n",
    "    \"http://localhost:7437/api/webhooks/outgoing\",\n",
    "    json=event_test_data,\n",
    "    headers=agixt.headers,\n",
    ")\n",
    "print(f\"Event types test webhook: {event_response.status_code}\")\n",
    "if event_response.status_code == 200:\n",
    "    print(\"✅ Webhook with different event types created successfully\")\n",
    "    event_webhook = event_response.json()\n",
    "    print(f\"Created webhook with events: {event_webhook.get('event_types', [])}\")\n",
    "else:\n",
    "    print(f\"❌ Failed to create event webhook: {event_response.text}\")\n",
    "\n",
    "# Test 3: Incoming webhook validation\n",
    "if incoming_webhook and isinstance(incoming_webhook, dict):\n",
    "    incoming_required = [\"id\", \"name\", \"webhook_id\", \"agent_id\"]\n",
    "    missing_incoming = [\n",
    "        field for field in incoming_required if field not in incoming_webhook\n",
    "    ]\n",
    "    if missing_incoming:\n",
    "        print(f\"❌ Incoming webhook missing fields: {missing_incoming}\")\n",
    "    else:\n",
    "        print(\"✅ Incoming webhook has all required fields\")\n",
    "else:\n",
    "    print(\"❌ Incoming webhook creation failed - cannot validate\")\n",
    "\n",
    "print(\"=== Webhook validation tests completed ===\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test webhook stats and logs endpoint response structure\n",
    "print(\"--- Validating webhook stats and logs response structure ---\")\n",
    "\n",
    "# Test webhook stats response structure\n",
    "stats_response = requests.get(\n",
    "    \"http://localhost:7437/api/webhooks/stats\",\n",
    "    headers=agixt.headers,\n",
    ")\n",
    "\n",
    "if stats_response.status_code == 200:\n",
    "    stats_data = stats_response.json()\n",
    "    print(\"✅ Webhook stats endpoint accessible\")\n",
    "\n",
    "    # Validate expected fields in stats response\n",
    "    expected_stats_fields = [\n",
    "        \"total_outgoing\",\n",
    "        \"total_incoming\",\n",
    "        \"active_outgoing\",\n",
    "        \"active_incoming\",\n",
    "    ]\n",
    "    missing_stats_fields = [\n",
    "        field for field in expected_stats_fields if field not in stats_data\n",
    "    ]\n",
    "\n",
    "    if missing_stats_fields:\n",
    "        print(f\"⚠️ Stats response missing expected fields: {missing_stats_fields}\")\n",
    "        print(f\"Available fields: {list(stats_data.keys())}\")\n",
    "    else:\n",
    "        print(\"✅ Stats response has all expected fields\")\n",
    "        print(f\"Stats summary: {stats_data}\")\n",
    "else:\n",
    "    print(\n",
    "        f\"❌ Webhook stats endpoint failed: {stats_response.status_code} - {stats_response.text}\"\n",
    "    )\n",
    "\n",
    "# Test webhook logs response structure\n",
    "logs_response = requests.get(\n",
    "    \"http://localhost:7437/api/webhooks/logs?limit=5\",\n",
    "    headers=agixt.headers,\n",
    ")\n",
    "\n",
    "if logs_response.status_code == 200:\n",
    "    logs_data = logs_response.json()\n",
    "    print(\"✅ Webhook logs endpoint accessible\")\n",
    "\n",
    "    if isinstance(logs_data, list):\n",
    "        print(f\"✅ Logs returned as list with {len(logs_data)} entries\")\n",
    "\n",
    "        if logs_data:\n",
    "            # Validate log entry structure\n",
    "            log_entry = logs_data[0]\n",
    "            expected_log_fields = [\"id\", \"webhook_id\", \"direction\", \"timestamp\"]\n",
    "            missing_log_fields = [\n",
    "                field for field in expected_log_fields if field not in log_entry\n",
    "            ]\n",
    "\n",
    "            if missing_log_fields:\n",
    "                print(f\"⚠️ Log entry missing expected fields: {missing_log_fields}\")\n",
    "                print(f\"Available fields: {list(log_entry.keys())}\")\n",
    "            else:\n",
    "                print(\"✅ Log entries have expected structure\")\n",
    "        else:\n",
    "            print(\"ℹ️ No webhook logs found (this is expected for new installations)\")\n",
    "    else:\n",
    "        print(f\"❌ Logs response should be a list, got {type(logs_data)}\")\n",
    "else:\n",
    "    print(\n",
    "        f\"❌ Webhook logs endpoint failed: {logs_response.status_code} - {logs_response.text}\"\n",
    "    )\n",
    "\n",
    "print(\"--- Endpoint structure validation completed ---\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Cleanup: Delete test webhooks and agent using requests\n",
    "# Get all outgoing webhooks and delete test ones\n",
    "response = requests.get(\n",
    "    \"http://localhost:7437/api/webhooks/outgoing\",\n",
    "    headers=agixt.headers,\n",
    ")\n",
    "if response.status_code == 200:\n",
    "    webhooks = response.json()\n",
    "    for webhook in webhooks:\n",
    "        if webhook.get(\"name\") == \"Test Webhook\":\n",
    "            delete_response = requests.delete(\n",
    "                f\"http://localhost:7437/api/webhooks/outgoing/{webhook['id']}\",\n",
    "                headers=agixt.headers,\n",
    "            )\n",
    "            if delete_response.status_code == 200:\n",
    "                print(f\"Deleted outgoing webhook: {webhook['name']}\")\n",
    "            else:\n",
    "                print(f\"Error deleting outgoing webhook: {delete_response.text}\")\n",
    "\n",
    "# Get all incoming webhooks and delete test ones\n",
    "response = requests.get(\n",
    "    \"http://localhost:7437/api/webhooks/incoming\",\n",
    "    headers=agixt.headers,\n",
    ")\n",
    "if response.status_code == 200:\n",
    "    webhooks = response.json()\n",
    "    for webhook in webhooks:\n",
    "        if webhook.get(\"name\") == \"GitHub Webhook\":\n",
    "            delete_response = requests.delete(\n",
    "                f\"http://localhost:7437/api/webhooks/incoming/{webhook['id']}\",\n",
    "                headers=agixt.headers,\n",
    "            )\n",
    "            if delete_response.status_code == 200:\n",
    "                print(f\"Deleted incoming webhook: {webhook['name']}\")\n",
    "            else:\n",
    "                print(f\"Error deleting incoming webhook: {delete_response.text}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Test updating an outgoing webhook using requests\n",
    "# First get the webhook ID from the created webhook or find an existing one\n",
    "webhook_id = None\n",
    "\n",
    "# Try to use the webhook we just created\n",
    "if created_webhook and isinstance(created_webhook, dict) and \"id\" in created_webhook:\n",
    "    webhook_id = created_webhook[\"id\"]\n",
    "    print(f\"Using recently created webhook ID: {webhook_id}\")\n",
    "else:\n",
    "    # If creation failed, try to find an existing webhook\n",
    "    print(\"No webhook from creation, checking for existing webhooks...\")\n",
    "    response = requests.get(\n",
    "        \"http://localhost:7437/api/webhooks/outgoing\",\n",
    "        headers=agixt.headers,\n",
    "    )\n",
    "    if response.status_code == 200:\n",
    "        webhooks = response.json()\n",
    "        if webhooks:\n",
    "            webhook_id = webhooks[0][\"id\"]\n",
    "            print(f\"Using existing webhook ID: {webhook_id}\")\n",
    "\n",
    "if webhook_id:\n",
    "    update_data = {\n",
    "        \"name\": \"Updated Test Webhook\",\n",
    "        \"description\": \"Updated webhook description\",\n",
    "        \"event_types\": [\"agent.created\", \"agent.deleted\", \"chat.completed\"],\n",
    "        \"active\": True,\n",
    "    }\n",
    "\n",
    "    response = requests.put(\n",
    "        f\"http://localhost:7437/api/webhooks/outgoing/{webhook_id}\",\n",
    "        json=update_data,\n",
    "        headers=agixt.headers,\n",
    "    )\n",
    "\n",
    "    if response.status_code == 200:\n",
    "        updated_webhook = response.json()\n",
    "        print(f\"Successfully updated webhook: {updated_webhook.get('name', 'Unknown')}\")\n",
    "        print(f\"Description: {updated_webhook.get('description', 'No description')}\")\n",
    "        print(f\"Event types: {updated_webhook.get('event_types', [])}\")\n",
    "        print(f\"Webhook ID: {updated_webhook.get('id', 'Unknown')}\")\n",
    "    else:\n",
    "        print(f\"Error updating webhook: {response.status_code} - {response.text}\")\n",
    "else:\n",
    "    print(\"No webhook available to update, skipping update test\")\n",
    "    print(\"This could mean webhook creation is failing or no webhooks exist\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Extension Commands\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ext = agixt.get_extensions()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get command arguments\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "command_args = agixt.get_command_args(command_name=\"Write to File\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create a new Agent\n",
    "\n",
    "Creates a new agent with the `ezlocalai` provider.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a new agent and capture the returned ID\n",
    "agent_name = \"test_agent\"\n",
    "add_agent_resp = agixt.add_agent(\n",
    "    agent_name=agent_name,\n",
    "    settings={\n",
    "        \"mode\": \"prompt\",\n",
    "        \"prompt_category\": \"Default\",\n",
    "        \"prompt_name\": \"Think About It\",\n",
    "        \"persona\": \"\",\n",
    "    },\n",
    ")\n",
    "# The response includes the agent ID\n",
    "test_agent_id = add_agent_resp.get(\"id\") or add_agent_resp.get(\"agent_id\")\n",
    "print(f\"Created agent with ID: {test_agent_id}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Extensions Available to Agent\n",
    "\n",
    "This function will get a list of extensions available to the agent as well as the required settings keys and available commands per extension. If the agent does not have the settings keys for the specific extension, the list of commands will be empty."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get extensions available to the agent by ID\n",
    "agent_extensions = agixt.get_agent_extensions(agent_id=test_agent_id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Execute a Command\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Execute a command using the agent ID\n",
    "command_execution = agixt.execute_command(\n",
    "    agent_id=test_agent_id,\n",
    "    command_name=\"Write to File\",\n",
    "    command_args={\"filename\": \"test files.txt\", \"text\": \"This is just a test!\"},\n",
    "    conversation_id=\"\",  # Empty string for new conversation\n",
    ")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get a list of all current Agents\n",
    "\n",
    "Any agents that you have created will be listed here. The `status` field is to say if the agent is currently running a task or not.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get a list of all agents with their IDs\n",
    "agents = agixt.get_agents()\n",
    "print(f\"Found {len(agents)} agents\")\n",
    "for a in agents:\n",
    "    print(f\"  - {a.get('name', 'N/A')} (id: {a.get('id', 'N/A')})\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Rename the test agent\n",
    "\n",
    "We will just rename it to `new_agent`.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Rename the agent using its ID\n",
    "new_agent_name = \"new_agent\"\n",
    "rename_agent_resp = agixt.rename_agent(agent_id=test_agent_id, new_name=new_agent_name)\n",
    "print(f\"Renamed agent: {rename_agent_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get the agent's settings\n",
    "\n",
    "This will get the settings for the agent we just created, this will tell you all commands available to the agent as well as all of the provider settings for the agent.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get the agent's config by ID\n",
    "agent_config = agixt.get_agentconfig(agent_id=test_agent_id)\n",
    "print(\n",
    "    f\"Agent config keys: {agent_config.keys() if isinstance(agent_config, dict) else 'N/A'}\"\n",
    ")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Update the agent's settings\n",
    "\n",
    "We'll just update the temperature from the default `0.7` to `0.8` to confirm that we can modify a setting.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Update the agent's settings by ID\n",
    "agent_config = agixt.get_agentconfig(agent_id=test_agent_id)\n",
    "agent_settings = agent_config[\"settings\"]\n",
    "# We'll just change the AI_TEMPERATURE setting for the test\n",
    "agent_settings[\"AI_TEMPERATURE\"] = 0.8\n",
    "update_agent_settings_resp = agixt.update_agent_settings(\n",
    "    agent_id=test_agent_id, settings=agent_settings\n",
    ")\n",
    "print(\"Update agent settings response:\", update_agent_settings_resp)\n",
    "agent_config = agixt.get_agentconfig(agent_id=test_agent_id)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get a list of the agent's commands\n",
    "\n",
    "This will get a list of all commands available to the agent.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get a list of commands for the agent by ID\n",
    "commands = agixt.get_commands(agent_id=test_agent_id)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Toggle a Command for the Agent\n",
    "\n",
    "We'll toggle the `Write to File` command to `true` to confirm that we can toggle a command.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Toggle the Write to File command using agent ID\n",
    "toggle_command_resp = agixt.toggle_command(\n",
    "    agent_id=test_agent_id, command_name=\"Write to File\", enable=True\n",
    ")\n",
    "print(f\"Toggle command response: {toggle_command_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Update Agent Commands\n",
    "\n",
    "In this example, we'll only change the `Convert Markdown to PDF` command to `False`, but we could change any (or all) of the commands with this API call."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Update agent commands using agent ID\n",
    "agent_config = agixt.get_agentconfig(agent_id=test_agent_id)\n",
    "if agent_config.get(\"commands\") is not None:\n",
    "    agent_commands = agent_config[\"commands\"]\n",
    "else:\n",
    "    agent_commands = {}\n",
    "agent_commands[\"Convert Markdown to PDF\"] = False\n",
    "update_agent_commands_resp = agixt.update_agent_commands(\n",
    "    agent_id=test_agent_id, commands=agent_commands\n",
    ")\n",
    "print(f\"Update commands response: {update_agent_commands_resp}\")\n",
    "agent_config = agixt.get_agentconfig(agent_id=test_agent_id)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create a new conversation\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a new conversation using agent ID\n",
    "conversation_resp = agixt.new_conversation(\n",
    "    agent_id=test_agent_id, conversation_name=\"Talk for Tests\"\n",
    ")\n",
    "talk_conversation_id = conversation_resp.get(\"id\")\n",
    "print(f\"Created conversation with ID: {talk_conversation_id}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Conversations\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get all conversations (returns dict with conversation IDs as keys)\n",
    "conversations = agixt.get_conversations()\n",
    "print(f\"Found {len(conversations)} conversations\")\n",
    "# conversations is a dict like {\"conv_id\": {\"name\": \"...\", \"agent_id\": \"...\", ...}}\n",
    "for conv_id, conv_data in list(conversations.items())[:5]:  # Show first 5\n",
    "    print(f\"  - {conv_data.get('name', 'N/A')} (id: {conv_id})\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Manual Conversation Message"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a new conversation for message tests\n",
    "msg_conv_resp = agixt.new_conversation(\n",
    "    agent_id=test_agent_id, conversation_name=\"AGiXT Conversation\"\n",
    ")\n",
    "agixt_conversation_id = msg_conv_resp.get(\"id\")\n",
    "print(f\"Created AGiXT Conversation with ID: {agixt_conversation_id}\")\n",
    "\n",
    "# Add messages using conversation ID\n",
    "agixt.new_conversation_message(\n",
    "    role=\"USER\",\n",
    "    conversation_id=agixt_conversation_id,\n",
    "    message=\"This is a test message from the user!\",\n",
    ")\n",
    "agixt.new_conversation_message(\n",
    "    role=\"new_agent\",\n",
    "    conversation_id=agixt_conversation_id,\n",
    "    message=\"This is a test message from the agent!\",\n",
    ")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Conversation Details\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get conversation details by ID\n",
    "conversation = agixt.get_conversation(\n",
    "    conversation_id=agixt_conversation_id, limit=100, page=1\n",
    ")\n",
    "print(f\"Got {len(conversation)} messages in conversation\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Fork a Conversation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Add extra messages to the conversation for forking\n",
    "agixt.new_conversation_message(\n",
    "    role=\"USER\",\n",
    "    conversation_id=agixt_conversation_id,\n",
    "    message=\"This is a test message from the user!\",\n",
    ")\n",
    "agixt.new_conversation_message(\n",
    "    role=\"new_agent\",\n",
    "    conversation_id=agixt_conversation_id,\n",
    "    message=\"This is a test message from the agent!\",\n",
    ")\n",
    "\n",
    "# Get updated conversation to get message IDs\n",
    "conversation = agixt.get_conversation(\n",
    "    conversation_id=agixt_conversation_id, limit=100, page=1\n",
    ")\n",
    "\n",
    "# Fork the conversation from the second message\n",
    "if len(conversation) >= 2:\n",
    "    message_id = conversation[1][\"id\"]\n",
    "    forked_resp = agixt.fork_conversation(\n",
    "        conversation_id=agixt_conversation_id, message_id=message_id\n",
    "    )\n",
    "    forked_conversation_id = (\n",
    "        forked_resp.get(\"id\") if isinstance(forked_resp, dict) else None\n",
    "    )\n",
    "    print(f\"Forked conversation ID: {forked_conversation_id}\")\n",
    "\n",
    "    # Get the forked conversation\n",
    "    if forked_conversation_id:\n",
    "        fork = agixt.get_conversation(conversation_id=forked_conversation_id)\n",
    "        print(f\"Forked conversation has {len(fork)} messages\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Delete Message from Conversation\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Delete a message from the conversation by IDs\n",
    "conversation = agixt.get_conversation(\n",
    "    conversation_id=agixt_conversation_id, limit=100, page=1\n",
    ")\n",
    "if len(conversation) > 0:\n",
    "    message_to_delete = conversation[0]\n",
    "    message_id = message_to_delete[\"id\"]\n",
    "    print(f\"Deleting message: {message_to_delete['message'][:50]}...\")\n",
    "    delete_msg_resp = agixt.delete_conversation_message(\n",
    "        conversation_id=agixt_conversation_id, message_id=message_id\n",
    "    )\n",
    "    print(f\"Delete response: {delete_msg_resp}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Delete a Conversation\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Delete the conversation by ID\n",
    "delete_conv_resp = agixt.delete_conversation(conversation_id=agixt_conversation_id)\n",
    "print(f\"Delete conversation response: {delete_conv_resp}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Have the Agent Learn from specified Text\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Learn text using agent ID\n",
    "text_learning = agixt.learn_text(\n",
    "    agent_id=test_agent_id,\n",
    "    user_input=\"What is AGiXT?\",\n",
    "    text=\"AGiXT is an open-source artificial intelligence automation platform.\",\n",
    "    collection_number=\"0\",\n",
    ")\n",
    "print(f\"Learn text response: {text_learning}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Have the Agent Learn from Files\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Zip"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8ed76a53",
   "metadata": {},
   "outputs": [],
   "source": [
    "import base64\n",
    "\n",
    "learn_file_path = \"test.zip\"\n",
    "with open(learn_file_path, \"rb\") as f:\n",
    "    learn_file_content = base64.b64encode(f.read()).decode(\"utf-8\")\n",
    "\n",
    "file_learning = agixt.learn_file(\n",
    "    agent_id=test_agent_id,\n",
    "    file_name=learn_file_path,\n",
    "    file_content=learn_file_content,\n",
    "    collection_number=\"0\",\n",
    ")\n",
    "print(f\"Learn zip file response: {file_learning}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### CSV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8613de23",
   "metadata": {},
   "outputs": [],
   "source": [
    "import base64\n",
    "\n",
    "learn_file_path = \"test.csv\"\n",
    "with open(learn_file_path, \"rb\") as f:\n",
    "    learn_file_content = base64.b64encode(f.read()).decode(\"utf-8\")\n",
    "\n",
    "file_learning = agixt.learn_file(\n",
    "    agent_id=test_agent_id,\n",
    "    file_name=learn_file_path,\n",
    "    file_content=learn_file_content,\n",
    "    collection_number=\"0\",\n",
    ")\n",
    "print(f\"Learn csv file response: {file_learning}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### XLS/XLSX"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bc92875b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import base64\n",
    "\n",
    "learn_file_path = \"test.xlsx\"\n",
    "with open(learn_file_path, \"rb\") as f:\n",
    "    learn_file_content = base64.b64encode(f.read()).decode(\"utf-8\")\n",
    "\n",
    "file_learning = agixt.learn_file(\n",
    "    agent_id=test_agent_id,\n",
    "    file_name=learn_file_path,\n",
    "    file_content=learn_file_content,\n",
    "    collection_number=\"0\",\n",
    ")\n",
    "print(f\"Learn xlsx file response: {file_learning}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DOC/DOCX"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0efb293d",
   "metadata": {},
   "outputs": [],
   "source": [
    "import base64\n",
    "\n",
    "learn_file_path = \"test.docx\"\n",
    "with open(learn_file_path, \"rb\") as f:\n",
    "    learn_file_content = base64.b64encode(f.read()).decode(\"utf-8\")\n",
    "\n",
    "file_learning = agixt.learn_file(\n",
    "    agent_id=test_agent_id,\n",
    "    file_name=learn_file_path,\n",
    "    file_content=learn_file_content,\n",
    "    collection_number=\"0\",\n",
    ")\n",
    "print(f\"Learn docx file response: {file_learning}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### PPT/PPTX"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5a48ad25",
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "import base64\n",
    "\n",
    "ppt_url = \"https://getsamplefiles.com/download/pptx/sample-1.pptx\"\n",
    "response = requests.get(ppt_url)\n",
    "learn_file_path = os.path.join(os.getcwd(), \"sample-1.pptx\")\n",
    "with open(learn_file_path, \"wb\") as f:\n",
    "    f.write(response.content)\n",
    "learn_file_content = base64.b64encode(response.content).decode(\"utf-8\")\n",
    "\n",
    "file_learning = agixt.learn_file(\n",
    "    agent_id=test_agent_id,\n",
    "    file_name=learn_file_path,\n",
    "    file_content=learn_file_content,\n",
    "    collection_number=\"0\",\n",
    ")\n",
    "print(f\"Learn pptx file response: {file_learning}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### PDF"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "23c01054",
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "import base64\n",
    "\n",
    "pdf_url = \"https://getsamplefiles.com/download/pdf/sample-1.pdf\"\n",
    "response = requests.get(pdf_url)\n",
    "learn_file_path = os.path.join(os.getcwd(), \"sample-1.pdf\")\n",
    "with open(learn_file_path, \"wb\") as f:\n",
    "    f.write(response.content)\n",
    "learn_file_content = base64.b64encode(response.content).decode(\"utf-8\")\n",
    "\n",
    "file_learning = agixt.learn_file(\n",
    "    agent_id=test_agent_id,\n",
    "    file_name=learn_file_path,\n",
    "    file_content=learn_file_content,\n",
    "    collection_number=\"0\",\n",
    ")\n",
    "print(f\"Learn pdf file response: {file_learning}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### TXT"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import base64\n",
    "\n",
    "learn_file_path = \"test.txt\"\n",
    "with open(learn_file_path, \"rb\") as f:\n",
    "    learn_file_content = base64.b64encode(f.read()).decode(\"utf-8\")\n",
    "\n",
    "file_learning = agixt.learn_file(\n",
    "    agent_id=test_agent_id,\n",
    "    file_name=learn_file_path,\n",
    "    file_content=learn_file_content,\n",
    "    collection_number=\"0\",\n",
    ")\n",
    "print(f\"Learn txt file response: {file_learning}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Have the Agent Learn from a URL\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Learn from a URL using agent ID\n",
    "url_learning = agixt.learn_url(\n",
    "    agent_id=test_agent_id,\n",
    "    url=\"https://josh-xt.github.io/AGiXT\",\n",
    "    collection_number=\"0\",\n",
    ")\n",
    "print(f\"Learn URL response: {url_learning}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get the Agents Memories\n",
    "\n",
    "Get some relevant memories from the agent about AGiXT.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get agent memories using agent ID\n",
    "memories = agixt.get_agent_memories(\n",
    "    agent_id=test_agent_id,\n",
    "    user_input=\"What can you tell me about AGiXT?\",\n",
    "    limit=10,\n",
    "    min_relevance_score=0.2,\n",
    "    collection_number=\"0\",\n",
    ")\n",
    "print(f\"Found {len(memories)} relevant memories\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Chat with the Agent\n",
    "\n",
    "Chat about the learned information with the agent.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Chat with the agent using agent ID and create a conversation\n",
    "chat_conv_resp = agixt.new_conversation(\n",
    "    agent_id=test_agent_id, conversation_name=\"Tell me about AGiXT\"\n",
    ")\n",
    "chat_conversation_id = chat_conv_resp.get(\"id\")\n",
    "\n",
    "agent_chat = agixt.chat(\n",
    "    agent_id=test_agent_id,\n",
    "    user_input=\"What can you tell me about AGiXT?\",\n",
    "    conversation_id=chat_conversation_id,\n",
    "    context_results=6,\n",
    ")\n",
    "print(f\"Chat response: {agent_chat[:200] if agent_chat else 'N/A'}...\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Delete a Memory\n",
    "\n",
    "Delete a specific memory by Memory ID.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get agent memories to find one to delete\n",
    "memories = agixt.get_agent_memories(\n",
    "    agent_id=test_agent_id,\n",
    "    user_input=\"What can you tell me about AGiXT?\",\n",
    "    limit=1,\n",
    "    min_relevance_score=0.2,\n",
    "    collection_number=\"0\",\n",
    ")\n",
    "# Remove the first memory\n",
    "if memories:\n",
    "    memory = memories[0]\n",
    "    memory_id = memory.get(\"id\")\n",
    "    print(f\"Memory: {memory}\")\n",
    "    if memory_id:\n",
    "        print(f\"Memory ID: {memory_id}\")\n",
    "        delete_memory_resp = agixt.delete_agent_memory(\n",
    "            agent_id=test_agent_id, memory_id=memory_id, collection_number=\"0\"\n",
    "        )\n",
    "        print(f\"Delete memory response: {delete_memory_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Wipe the agents memories\n",
    "\n",
    "This is necessary if you want the agent to serve a different purpose than its original intent after it has learned things. It may inject unnecessary context into the conversation if you don't wipe its memory and try to give it a different purpose, even temporarily.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Wipe agent memories using agent ID\n",
    "# Note: Use this function with caution as it will erase the agent's memory.\n",
    "wipe_mem_resp = agixt.wipe_agent_memories(agent_id=test_agent_id, collection_number=\"0\")\n",
    "print(f\"Wipe memories response: {wipe_mem_resp}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Instruct the Agent to do something\n",
    "\n",
    "We'll do something simple with it for the sake of the basic example, we'll just tell it to `Tell me the capital of France`.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Instruct the agent using agent ID and conversation ID\n",
    "instruct_conv_resp = agixt.new_conversation(\n",
    "    agent_id=test_agent_id, conversation_name=\"Talk for Tests 2\"\n",
    ")\n",
    "instruct_conversation_id = instruct_conv_resp.get(\"id\")\n",
    "\n",
    "instruct_resp = agixt.instruct(\n",
    "    agent_id=test_agent_id,\n",
    "    user_input=\"Save a file with the capital of France in it called 'france.txt'.\",\n",
    "    conversation_id=instruct_conversation_id,\n",
    ")\n",
    "print(f\"Instruct response: {instruct_resp[:200] if instruct_resp else 'N/A'}...\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Prompt the Agent\n",
    "\n",
    "Use a custom Prompt Template to prompt the agent. For our example, we'll use our \"Write a Poem\" prompt template to have the agent write a poem for us about dragons.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Prompt the agent with a custom prompt template using agent ID\n",
    "prompt_name = \"Write a Haiku\"\n",
    "user_input = \"Show me 2.\"\n",
    "# The \"Write a Haiku\" prompt only requires one argument, \"subject\".\n",
    "# We'll ask the AI to write a poem about dragons.\n",
    "prompt_args = {\n",
    "    \"user_input\": user_input,\n",
    "    \"subject\": \"dragons\",\n",
    "    \"websearch\": False,\n",
    "    \"websearch_depth\": 0,\n",
    "    \"context_results\": 0,\n",
    "    \"shots\": 1,\n",
    "    \"conversation_name\": instruct_conversation_id,\n",
    "}\n",
    "\n",
    "agent_prompt_resp = agixt.prompt_agent(\n",
    "    agent_id=test_agent_id,\n",
    "    prompt_name=prompt_name,\n",
    "    prompt_args=prompt_args,\n",
    ")\n",
    "print(f\"Prompt response: {agent_prompt_resp[:200] if agent_prompt_resp else 'N/A'}...\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get a list of Chains available to use\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get a list of chains (returns list with IDs)\n",
    "chains = agixt.get_chains()\n",
    "print(f\"Found {len(chains)} chains\")\n",
    "for c in chains[:5]:  # Show first 5\n",
    "    print(f\"  - {c.get('chainName', 'N/A')} (id: {c.get('id', 'N/A')})\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create a new chain\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a new chain and capture the ID\n",
    "chain_name = \"Write another Poem\"\n",
    "add_chain_resp = agixt.add_chain(chain_name=chain_name)\n",
    "test_chain_id = add_chain_resp.get(\"id\")\n",
    "print(f\"Created chain with ID: {test_chain_id}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Rename the chain\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Rename the chain using ID\n",
    "new_chain_name = \"Poem Writing Chain\"\n",
    "rename_chain_resp = agixt.rename_chain(chain_id=test_chain_id, new_name=new_chain_name)\n",
    "print(f\"Rename chain response: {rename_chain_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Add Chain Steps\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Add chain steps using chain ID and agent ID\n",
    "add_step_resp = agixt.add_step(\n",
    "    chain_id=test_chain_id,\n",
    "    step_number=1,\n",
    "    agent_id=test_agent_id,\n",
    "    prompt_type=\"Prompt\",\n",
    "    prompt={\n",
    "        \"prompt_name\": \"Write a Poem\",\n",
    "        \"subject\": \"Artificial Intelligence\",\n",
    "    },\n",
    ")\n",
    "print(f\"Add step 1 response: {add_step_resp}\")\n",
    "\n",
    "add_step_resp = agixt.add_step(\n",
    "    chain_id=test_chain_id,\n",
    "    step_number=2,\n",
    "    agent_id=test_agent_id,\n",
    "    prompt_type=\"Prompt\",\n",
    "    prompt={\n",
    "        \"prompt_name\": \"Write a Poem\",\n",
    "        \"subject\": \"Quantum Computers\",\n",
    "    },\n",
    ")\n",
    "print(f\"Add step 2 response: {add_step_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get the content of the chain\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get the chain content by ID\n",
    "chain = agixt.get_chain(chain_id=test_chain_id)\n",
    "print(f\"Chain: {chain}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Chain Arguments\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get chain arguments by ID\n",
    "chain_args = agixt.get_chain_args(chain_id=test_chain_id)\n",
    "print(f\"Chain args: {chain_args}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Modify a chain step\n",
    "\n",
    "Instead of the subject of the poem just being Artificial Intelligence, we'll change it to be Artificial General Intelligence.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Update a chain step using chain ID and agent ID\n",
    "update_step_resp = agixt.update_step(\n",
    "    chain_id=test_chain_id,\n",
    "    step_number=1,\n",
    "    agent_id=test_agent_id,\n",
    "    prompt_type=\"Prompt\",\n",
    "    prompt={\n",
    "        \"prompt_name\": \"Write a Poem\",\n",
    "        \"subject\": \"Artificial General Intelligence\",\n",
    "    },\n",
    ")\n",
    "print(f\"Update step response: {update_step_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Move the chain step\n",
    "\n",
    "When you move a step, it will automatically reassign the order of the steps to match the new order. If there are only 2 steps like in our case, it will just swap them.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Move a chain step using chain ID\n",
    "move_step_resp = agixt.move_step(\n",
    "    chain_id=test_chain_id, old_step_number=1, new_step_number=2\n",
    ")\n",
    "print(f\"Move step response: {move_step_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Delete a step from the chain\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Delete a step from the chain using chain ID\n",
    "delete_step_resp = agixt.delete_step(chain_id=test_chain_id, step_number=2)\n",
    "print(f\"Delete step response: {delete_step_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Add a Command to the Chain\n",
    "\n",
    "We'll write the result to a file for an example.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Add a command to the chain using chain ID and agent ID\n",
    "add_step_resp = agixt.add_step(\n",
    "    chain_id=test_chain_id,\n",
    "    step_number=2,\n",
    "    agent_id=test_agent_id,\n",
    "    prompt_type=\"Command\",\n",
    "    prompt={\n",
    "        \"command_name\": \"Write to File\",\n",
    "        \"filename\": \"{user_input}.txt\",\n",
    "        \"text\": \"Poem:\\n{STEP1}\",\n",
    "    },\n",
    ")\n",
    "print(f\"Add command step response: {add_step_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Run the chain\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Run the chain using chain ID\n",
    "user_input = \"Super Poems\"\n",
    "run_chain_resp = agixt.run_chain(\n",
    "    chain_id=test_chain_id, user_input=user_input, from_step=1\n",
    ")\n",
    "print(f\"Run chain response: {run_chain_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Delete the chain\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Delete the chain using chain ID\n",
    "delete_chain_resp = agixt.delete_chain(chain_id=test_chain_id)\n",
    "print(f\"Delete chain response: {delete_chain_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get a list of prompts available to use\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get all prompts with IDs\n",
    "prompts = agixt.get_prompts(prompt_category=\"Default\")\n",
    "print(f\"Found {len(prompts)} prompts in Default category\")\n",
    "# Each prompt has: name, category, id\n",
    "for p in prompts[:5]:  # Show first 5\n",
    "    print(f\"  - {p['name']} (id: {p.get('id', 'N/A')})\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get the content of a prompt\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get a prompt by ID (use the first prompt from the list)\n",
    "if prompts:\n",
    "    prompt_id = prompts[0][\"id\"]\n",
    "    get_prompt_resp = agixt.get_prompt(prompt_id=prompt_id)\n",
    "    print(f\"Got prompt: {get_prompt_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create a new prompt\n",
    "\n",
    "We'll make a basic prompt that asks the AI to tell us a short story about a subject. The subject is not yet defined, it would be defined in a chain. Using `{variable_name}` in a prompt will allow you to define the variable in a chain and have it be used in the prompt.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a new prompt and capture the returned ID\n",
    "add_prompt_resp = agixt.add_prompt(\n",
    "    prompt_name=\"Short Story\",\n",
    "    prompt=\"Tell me a short story about {subject}\",\n",
    "    prompt_category=\"Default\",\n",
    ")\n",
    "short_story_prompt_id = add_prompt_resp.get(\"id\")\n",
    "print(f\"Created prompt with ID: {short_story_prompt_id}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get the prompt variables\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get prompt arguments by ID\n",
    "get_prompt_args_resp = agixt.get_prompt_args(prompt_id=short_story_prompt_id)\n",
    "print(f\"Prompt args: {get_prompt_args_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Update the prompt content\n",
    "\n",
    "We'll ask it to `Add a dragon to the story somehow` in the prompt to make the short story more interesting.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Update the prompt content by ID\n",
    "update_prompt_resp = agixt.update_prompt(\n",
    "    prompt_id=short_story_prompt_id,\n",
    "    prompt=\"Tell me a short story about {subject}. Add a dragon to the story somehow.\",\n",
    ")\n",
    "print(f\"Update response: {update_prompt_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Delete the prompt\n",
    "\n",
    "If you don't want the prompt anymore, delete it.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Delete the prompt by ID\n",
    "delete_prompt_resp = agixt.delete_prompt(prompt_id=short_story_prompt_id)\n",
    "print(f\"Delete response: {delete_prompt_resp}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Delete the Agent\n",
    "\n",
    "If you are done with the agent and don't want or need it anymore, you can delete it along with everything associated with it, such as its memories, settings, and history. The Agent isn't just fired, it is dead.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Delete the agent using agent ID\n",
    "delete_agent_resp = agixt.delete_agent(agent_id=test_agent_id)\n",
    "print(f\"Delete agent response: {delete_agent_resp}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## OpenAI Style Endpoint Tests\n",
    "\n",
    "### Get Embeddings\n",
    "[OpenAI API Reference](https://platform.openai.com/docs/api-reference/embeddings)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Modify this prompt to generate different outputs\n",
    "prompt = \"Tacos are great.\"\n",
    "\n",
    "response = openai.embeddings.create(\n",
    "    input=prompt,\n",
    "    model=agent_name,\n",
    ")\n",
    "print(response.data[0].embedding)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Chat Completion Tests\n",
    "\n",
    "[OpenAI API Reference](https://platform.openai.com/docs/api-reference/chat)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Modify this prompt to generate different outputs\n",
    "prompt = \"Write a short poem about Pikachu with a picture.\"\n",
    "\n",
    "\n",
    "response = openai.chat.completions.create(\n",
    "    model=agent_name,  # Model is Agent Name\n",
    "    messages=[{\"role\": \"user\", \"content\": prompt}],\n",
    "    stream=False,\n",
    "    user=\"Pikachu Poem\",  # User is Conversation Name\n",
    ")\n",
    "display_content(response.choices[0].message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Streaming Chat Completion Test\n",
    "\n",
    "Test the new streaming functionality that allows real-time streaming of AI responses.\n",
    "\n",
    "[OpenAI API Reference - Streaming](https://platform.openai.com/docs/api-reference/chat/streaming)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "import json\n",
    "\n",
    "# Test streaming chat completion\n",
    "prompt = \"Tell me a short story about a robot learning to paint. Make it creative and engaging.\"\n",
    "\n",
    "print(\"🎬 Starting streaming test...\")\n",
    "print(\"=\" * 60)\n",
    "print(\"Response will appear in real-time:\")\n",
    "print(\"-\" * 60)\n",
    "\n",
    "start_time = time.time()\n",
    "\n",
    "try:\n",
    "    # Create streaming request\n",
    "    stream = openai.chat.completions.create(\n",
    "        model=agent_name,\n",
    "        messages=[{\"role\": \"user\", \"content\": prompt}],\n",
    "        stream=True,\n",
    "        max_tokens=300,\n",
    "        temperature=0.7,\n",
    "        user=\"Streaming Test\",\n",
    "    )\n",
    "\n",
    "    # Process streaming response\n",
    "    full_response = \"\"\n",
    "    chunk_count = 0\n",
    "\n",
    "    for chunk in stream:\n",
    "        chunk_count += 1\n",
    "        if chunk.choices[0].delta.content is not None:\n",
    "            content = chunk.choices[0].delta.content\n",
    "            full_response += content\n",
    "            print(content, end=\"\", flush=True)\n",
    "\n",
    "        # Check if streaming is complete\n",
    "        if chunk.choices[0].finish_reason == \"stop\":\n",
    "            break\n",
    "\n",
    "    end_time = time.time()\n",
    "\n",
    "    print(\"\\n\" + \"-\" * 60)\n",
    "    print(f\"✅ Streaming completed successfully!\")\n",
    "    print(f\"📊 Statistics:\")\n",
    "    print(f\"   • Total chunks received: {chunk_count}\")\n",
    "    print(f\"   • Total characters: {len(full_response)}\")\n",
    "    print(f\"   • Time taken: {end_time - start_time:.2f} seconds\")\n",
    "    print(\n",
    "        f\"   • Average chars/second: {len(full_response)/(end_time - start_time):.1f}\"\n",
    "    )\n",
    "    print(\"=\" * 60)\n",
    "\n",
    "except Exception as e:\n",
    "    print(f\"❌ Streaming test failed: {str(e)}\")\n",
    "    print(\n",
    "        \"This could indicate that streaming is not properly implemented or the agent is not available.\"\n",
    "    )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Vision Test\n",
    "The model used for tests does not have vision, but this example is here to show how you would use the endpoint if you had a model that could process images."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "response = openai.chat.completions.create(\n",
    "    model=agent_name,\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": [\n",
    "                {\"type\": \"text\", \"text\": \"Describe each stage of this image.\"},\n",
    "                {\n",
    "                    \"type\": \"image_url\",\n",
    "                    \"image_url\": {\n",
    "                        \"url\": f\"https://www.visualwatermark.com/images/add-text-to-photos/add-text-to-image-3.webp\"\n",
    "                    },\n",
    "                },\n",
    "            ],\n",
    "        },\n",
    "    ],\n",
    "    user=\"Vision Test\",\n",
    ")\n",
    "display_content(response.choices[0].message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### File Upload Test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import base64\n",
    "\n",
    "# Download csv to hurricanes.csv\n",
    "csv_url = \"https://people.sc.fsu.edu/~jburkardt/data/csv/hurricanes.csv\"\n",
    "response = requests.get(csv_url)\n",
    "base64_encoded_file = base64.b64encode(response.content).decode(\"utf-8\")\n",
    "data_url = f\"data:application/csv;base64,{base64_encoded_file}\"\n",
    "\n",
    "response = openai.chat.completions.create(\n",
    "    model=agent_name,\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"analyze_user_input\": \"false\",\n",
    "            \"content\": [\n",
    "                {\n",
    "                    \"type\": \"text\",\n",
    "                    \"text\": \"Which month had the most hurricanes according to the data provided?\",\n",
    "                },\n",
    "                {\n",
    "                    \"type\": \"file_url\",\n",
    "                    \"file_url\": {\n",
    "                        \"url\": data_url,\n",
    "                    },\n",
    "                },\n",
    "            ],\n",
    "        },\n",
    "    ],\n",
    "    user=\"Data Analysis\",\n",
    ")\n",
    "display_content(response.choices[0].message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Websearch Test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Modify this prompt to generate different outputs\n",
    "prompt = \"What are the latest critical windows vulnerabilities that have recently been patched in the past week?\"\n",
    "\n",
    "\n",
    "response = openai.chat.completions.create(\n",
    "    model=agent_name,\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"websearch\": \"true\",\n",
    "            \"websearch_depth\": \"2\",\n",
    "            \"content\": prompt,\n",
    "        }\n",
    "    ],\n",
    "    stream=False,\n",
    "    user=\"Windows Vulnerabilities\",\n",
    ")\n",
    "display_content(response.choices[0].message.content)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
